
#include "CH58x_common.h"
#include "zqm_global.h"
#include "zqm_module.h"
#include "hal_mcu.h"

// 电池侦测计数
volatile unsigned int hal_battery_plus = 0;

// 读取GPIO状态
// GPIOA_ReadITFlagPort(GPIO_Pin_15);
// GPIOA_ClearITFlagBit(GPIO_Pin_15);

// watch dog function -----------------------------------------------------------------------------------------------
void WdtClean(void)
{
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
    SAFEOPERATE;
    R8_WDOG_COUNT = 0;
    R8_SAFE_ACCESS_SIG = 0;
    zq_rtc_wdt_10s = 0;   // clear RTC simulator 10s watchdog
}

// HAL GPIO functions -----------------------------------------------------------------------------------------------
void GPIOInit_Normal(void)
{
    GPIOPinRemap(DISABLE, RB_PIN_UART3);                // 坑，boot程序中配置到TXD3没有还原，这里还原
    GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);        // config all IO to PD firstly
    GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);

    GPIO_ModeCfg(zy_ios.uart1_rx, GPIO_ModeIN_Floating);    //UART1 RX
    GPIO_ModeCfg(zy_ios.uart1_tx, GPIO_ModeOut_PP_5mA);     //UART1 TX

    GPIO_ModeCfg(zy_ios.fan, GPIO_ModeOut_PP_20mA);          // FAN_EN
    GPIO_ResetBits(zy_ios.fan);                              // init turn off fan 
    GPIO_ModeCfg(zy_ios.condenser_fan, GPIO_ModeOut_PP_20mA);// CONDENSER FAN
    GPIO_ModeCfg(zy_ios.light, GPIO_ModeOut_PP_20mA);        // light
    GPIO_ResetBits(zy_ios.condenser_fan);                    //init turn off fan 
    GPIO_ModeCfg(zy_ios.melt, GPIO_ModeOut_PP_20mA);         // Defrosting solenoid valve
    GPIO_ResetBits(zy_ios.melt);                             //init turn off valve
    GPIO_ModeCfg(zy_ios.cat1, GPIO_ModeOut_PP_20mA);         //CAT1_PWR_EN
    GPIO_ResetBits(zy_ios.cat1);                            //init turn off cat1 

    GPIO_ModeCfg(zy_ios.periph_pow, GPIO_ModeOut_PP_5mA);     //PW_CTL
#if (ZQ_DISPLAY_PANEL_TYPE != DPT_INTEGRAL_326)    // 预先给显示面板电容充个电, 不然直接拉PW_CTL, 会电流过大, 导致单片机复位, 326不需要
    GPIO_ModeCfg(zy_ios.dis_stb, GPIO_ModeOut_PP_20mA);     //LED_STB_CN
    GPIO_ModeCfg(zy_ios.dis_clk, GPIO_ModeOut_PP_20mA);     //LED_CLK_CN
    GPIO_ModeCfg(zy_ios.dis_dio, GPIO_ModeOut_PP_20mA);     //LED_DIO_CN
    GPIO_SetBits(zy_ios.dis_stb);   // 预先给显示面板电容充个电, 不然直接拉PW_CTL, 会电流过大, 导致单片机复位
    GPIO_SetBits(zy_ios.dis_clk);
    GPIO_SetBits(zy_ios.dis_dio);
    DelayMs(10);
#endif
   GPIO_ResetBits(zy_ios.periph_pow);

    GPIO_ModeCfg(zy_ios.uart0_tx, GPIO_ModeOut_PP_5mA);     //UART0 TX
    GPIO_ModeCfg(zy_ios.uart0_rx, GPIO_ModeIN_Floating);    //UART0 RX

    GPIO_ModeCfg(zy_ios.uart2_tx, GPIO_ModeOut_PP_5mA); 	//UART2 TX
    GPIO_ModeCfg(zy_ios.uart2_rx, GPIO_ModeIN_Floating);	//UART2 RX
    GPIO_ModeCfg(zy_ios.motor, GPIO_ModeOut_PP_20mA);	//MOTOR_EN
    GPIO_ResetBits(zy_ios.motor);                        //init turn off mnotor 

    GPIO_ModeCfg(zy_ios.ntc1_adc, GPIO_ModeIN_Floating);	//TEM_SENSOR1
    GPIO_ModeCfg(zy_ios.ntc2_adc, GPIO_ModeIN_Floating);	//TEM_SENSOR2
    GPIO_ModeCfg(zy_ios.det_door1, GPIO_ModeIN_PU);			//DOOR
    GPIO_ModeCfg(zy_ios.det_12v, GPIO_ModeIN_Floating);	    //DET_12V, 建议配置floating模式
    GPIO_ModeCfg(zy_ios.batt_adc, GPIO_ModeIN_Floating);	//ADC_BATT
    GPIO_ModeCfg(zy_ios.det_human, GPIO_ModeIN_PD);			//BODY_CHECK
    GPIO_ModeCfg(zy_ios.det_sys_switch, GPIO_ModeIN_PU);	//SYS_DET--//LAMP_EN
    GPIO_ModeCfg(zy_ios.heater, GPIO_ModeOut_PP_20mA);	//LIGHT_EN//Heater
    GPIO_ModeCfg(zy_ios.batt_chrg, GPIO_ModeIN_Floating);	//
    GPIO_ModeCfg(zy_ios.batt_stdby, GPIO_ModeIN_Floating);	//STDBY

    // 开GPIO中断
    PFIC_EnableIRQ(GPIO_A_IRQn);
    PFIC_EnableIRQ(GPIO_B_IRQn);
}

void GPIOInit_Sleep(void)
{
    GPIOPinRemap(DISABLE, RB_PIN_UART3);                // 坑，boot程序中配置到TXD3没有还原，这里还原
    GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);        // config all IO to PD firstly
    GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PD);
    GPIO_ModeCfg(zy_ios.periph_pow, GPIO_ModeOut_PP_5mA);     //PW_CTL
    GPIO_SetBits(zy_ios.periph_pow);
    GPIO_ModeCfg(zy_ios.uart0_tx, GPIO_ModeIN_PU);          //UART0 TX - 有电平转换电路, 接到VCC
    GPIO_ModeCfg(zy_ios.uart0_rx, GPIO_ModeIN_PU);          //UART0 RX - 有电平转换电路, 接到VCC
    GPIO_ModeCfg(zy_ios.batt_adc, GPIO_ModeIN_PU);	        //ADC_BATT, 电池会对这个脚放电
    GPIO_ModeCfg(zy_ios.batt_chrg, GPIO_ModeIN_PU);	        //CHRG
    GPIO_ModeCfg(zy_ios.batt_stdby, GPIO_ModeIN_PU);	    //STDBY

    // 开GPIO中断 - 增加了12v侦测唤醒，目的是小概率睡眠RTC唤醒失效时，增加上电唤醒保护
    PFIC_EnableIRQ(GPIO_A_IRQn);
    PFIC_EnableIRQ(GPIO_B_IRQn);
    GPIO_ModeCfg(zy_ios.det_12v, GPIO_ModeIN_PU);
    GPIO_ITModeCfg(zy_ios.det_12v, GPIO_ITMode_RiseEdge);          // 启动电源侦测中断, 上升沿触发
    GPIO_EnableIRQ(zy_ios.batt_chrg, DISABLE);                      // 关闭电池侦测中断, 防止唤醒干扰
    GPIO_EnableIRQ(zy_ios.det_human, DISABLE);                     // 关闭人流侦测中断, 防止唤醒干扰
    
#if (ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_326)    // 以下326需要控制截断共阳三极管，其它类型面板需不需要
    GPIOB_ModeCfg(IO_DISP_DIP_0, GPIO_ModeIN_PU);   //LED DIP1 
    GPIOB_ModeCfg(IO_DISP_DIP_1, GPIO_ModeIN_PU);   //LED DIP2 
    GPIOB_ModeCfg(IO_DISP_DIP_2, GPIO_ModeIN_PU);   //LED DIP3 
    GPIOB_ModeCfg(IO_DISP_DIP_3, GPIO_ModeIN_PU);   //LED DIP4 
    GPIOB_SetBits(IO_DISP_DIP_0);
    GPIOB_SetBits(IO_DISP_DIP_1);
    GPIOB_SetBits(IO_DISP_DIP_2);
    GPIOB_SetBits(IO_DISP_DIP_3);
#endif
}
//  -----------------------------------------------------------------------------------------------
void MotoSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.motor) : GPIO_ResetBits(zy_ios.motor);
}
void FanSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.fan) : GPIO_ResetBits(zy_ios.fan);
}
void CondenserFanSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.condenser_fan) : GPIO_ResetBits(zy_ios.condenser_fan);
}
void HeaterSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.heater) : GPIO_ResetBits(zy_ios.heater);
}
void MeltSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.melt) : GPIO_ResetBits(zy_ios.melt);
}
void LightSwitch(int isOn)
{
    isOn ? GPIO_SetBits(zy_ios.light) : GPIO_ResetBits(zy_ios.light);
}
int GPIOReadDoorState(void)
{
#if (ZQ_FUNC_DOOR1 == 1)
    return GPIO_ReadPortPin(zy_ios.det_door1) ? 1 : 0;
#endif
    return 0;
}
int GPIOReadSystemSwitchState(void)
{
#if (ZQ_FUNC_HARD_SWITCH == 1)
    return GPIO_ReadPortPin(zy_ios.det_sys_switch) ? 0 : 1; // 反相
#endif
    return 1;
}
int GPIOReadHumanSensor(void)
{
#if (ZQ_FUNC_HUMAN == 1)
    return GPIO_ReadPortPin(zy_ios.det_human) ? 1 : 0;
#endif
    return 0;
}

// time functions ------------------------------------------------------------------------------------
// RTC 1s timer init
void RtcInit_1s(void)
{
    LClk32K_Select(Clk32K_LSI);         // select inter 32khz crystal 
    RTC_InitTime(2024, 1, 1, 0, 0, 0);  // RTC时钟初始化当前时间
    RTC_TMRFunCfg(Period_1_S);          // 1s定时
    // 配置睡眠唤醒的方式   - RTC唤醒，定时模式
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
    SAFEOPERATE;
    R8_SLP_WAKE_CTRL |= RB_SLP_RTC_WAKE;    // RTC唤醒
    // R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN;  // 触发模式
    R8_RTC_MODE_CTRL |= RB_RTC_TMR_EN;      // 定时模式
    R8_SAFE_ACCESS_SIG = 0;
    zq_timer_rtc_s = zq_rtc_wdt_10s = zq_timer_rtc_s_pow = 0;
    PFIC_EnableIRQ(RTC_IRQn);
}
void M0InitTimer(void)
{
    Calibration_LSI(Level_128);             // 校准RTC
    uint32_t irq;
    SYS_DisableAllIrq(&irq); 
    RtcInit_1s(); // 启动1s RTC定时
    TMR0_TimerInit(GetSysClock() / 1000);  // 设置定时器0时间 1ms
    TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 开启定时器0中断
    PFIC_EnableIRQ(TMR0_IRQn);
    // 启动tick计时功能
    SysTick_Config((uint64_t)(-1));     // 最大溢出 = 不重新装载cnt计数器
    PFIC_DisableIRQ(SysTick_IRQn);   // 关闭SysTick中断
	// clear tick timer
    zq_timer_50ms = zq_timer_s = 0;
    SYS_RecoverIrq(irq);
}
// only reset zq_timer_50ms and zq_timer_s
void M0TimerClear(void)
{
    for(uint32_t t = zq_timer_50ms; t == zq_timer_50ms; ); // 等待对齐50ms, 保证timer均匀
    zq_timer_50ms = zq_timer_s = 0;
    zq_last_tick = SysTick->CNT;
}

// interrupt functions -------------------------------------------------------------------------
// SysTick_Handler 定时中断 1ms
// __INTERRUPT
// __HIGH_CODE
// void SysTick_Handler(void) 
// {
//     uint32_t span = 0;
//     SysTick->SR &= 0XFFFFFFFE;
//     span = (uint32_t)(SysTick->CNT - zq_last_tick);
//     if (span >= TASK_PERIOD*60000){ // 60MHZ
//         zq_timer_50ms = (zq_timer_50ms >= 0xffffffd2) ? TASK_PERIOD : (zq_timer_50ms + TASK_PERIOD); // 主任务循环前开始计时, 50ms精度, 单位1ms, 基于高速时钟。主循环前会清零, 约49天多会溢出, 溢出后跳过0重新由TASK_PERIOD开始, 可以用来=0判断初始化。是大部分系统上电（规格书定义真正上电开始是自检后）计时的依据，不能用于长期累加计时.
//         zq_timer_s += (zq_timer_50ms > 0 && zq_timer_50ms % 1000 == 0) ? 1 : 0; // 主任务循环前开始计时, 1s精度, 基于高速时钟。主循环前会清零,
//         zq_last_tick += TASK_PERIOD;
//     }
// }
__INTERRUPT
__HIGH_CODE
void TMR0_IRQHandler(void) // TMR0 定时中断
{
    static int span = 0;
    span++;
    // uint32_t span = 0;
    TMR0_ClearITFlag(TMR0_3_IT_CYC_END); // 清除中断标志
    // span = (uint32_t)(SysTick->CNT - zq_last_tick);
    if (span >= TASK_PERIOD){ 
        zq_timer_50ms = (zq_timer_50ms >= 0xffffffd2) ? TASK_PERIOD : (zq_timer_50ms + TASK_PERIOD); // 主任务循环前开始计时, 50ms精度, 单位1ms, 基于高速时钟。主循环前会清零, 约49天多会溢出, 溢出后跳过0重新由TASK_PERIOD开始, 可以用来=0判断初始化。是大部分系统上电（规格书定义真正上电开始是自检后）计时的依据，不能用于长期累加计时.
        zq_timer_s += (zq_timer_50ms > 0 && zq_timer_50ms % 1000 == 0) ? 1 : 0; // 主任务循环前开始计时, 1s精度, 基于高速时钟。主循环前会清零,
        // zq_last_tick += (TASK_PERIOD*60000);
        span = 0;
    }
#ifdef ZY_DRV_DISP_KEY_MCU582 // using cpu to refresh led and query keys
#ifndef ZQ_SIMULATOR 
    extern void DrvDispAndKey_2ms(void);
    if (span % 2 == 0) {
        DrvDispAndKey_2ms();
    }
#endif
#endif
}
// RTC_IRQHandler 定时中断
__INTERRUPT
__HIGH_CODE
void RTC_IRQHandler(void)
{
    // kaygle modified 20240229 修改，避开休眠唤醒瞬间，不能有flash操作，不能调用RTC_GetITFlag 和 RTC_ClearITFlag函数
    // if (RTC_GetITFlag(RTC_TMR_EVENT)) {
    //     RTC_ClearITFlag(RTC_TMR_EVENT);
    //     zy_timer_s_lp++;
    //     if(++zy_watchdog_lp > 10)  // 模拟看门狗(5s重启)，主要是在休眠模式下，WDG是基于高速时钟的，不起作用，增加个10秒的软件保护，防止低功耗情况下死机(比如电池模式下，静电打死)。普通模式下也可以用，多一层保护
    //         SYS_ResetExecute();
    // }
    // if (RTC_GetITFlag(RTC_TRIG_EVENT)) {
    //     RTC_ClearITFlag(RTC_TRIG_EVENT);
    //     //        RTCTigFlag= 1;
    // }
    if (R8_RTC_FLAG_CTRL & RB_RTC_TMR_FLAG) {
        R8_RTC_FLAG_CTRL = RB_RTC_TMR_CLR;
        zq_timer_rtc_s++;
        zq_timer_rtc_s_pow++;
        if (++zq_rtc_wdt_10s >= 10)  // 模拟看门狗(5s重启)，主要是在休眠模式下，WDG是基于高速时钟的，不起作用，增加个10秒的软件保护，防止低功耗情况下死机(比如电池模式下，静电打死)。普通模式下也可以用，多一层保护
            SYS_ResetExecute();
    }
    if (R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG) {
        R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR;
        //        RTCTigFlag= 1;
    }
}

#if (ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_3y) // 圆角一体显示使用老版的板子，电池侦测在GPIOB
__INTERRUPT
__HIGH_CODE
void GPIOB_IRQHandler(void)
{
    uint16_t flag;
    uint32_t pin = (zy_ios.batt_chrg | ZyGPIO_MASK);
    flag = GPIOB_ReadITFlagPort();
    if ((flag & pin) != 0) {                     // 电池侦测, 电池芯片脉冲计数。
        GPIOB_ClearITFlagBit((uint16_t)pin);     // clear interruption flag
        hal_battery_plus++;
    }
}
#else
__INTERRUPT
__HIGH_CODE
void GPIOA_IRQHandler(void)
{
    uint16_t flag;
    uint32_t pin = (zy_ios.batt_chrg | ZyGPIO_MASK);
    flag = GPIOA_ReadITFlagPort();
    if ((flag & pin) != 0) {                     // 电池侦测, 电池芯片脉冲计数。
        GPIOA_ClearITFlagBit((uint16_t)pin);     // clear interruption flag
        hal_battery_plus++;
    }
}
#endif


// power functions -----------------------------------------------------------------------------------------------
// 启动睡眠
__HIGH_CODE
void McuSleep(void)
{
#ifdef ZQ_SIMULATOR
    Sleep(1000);
#else
    // 注意当主频为80M时，Sleep睡眠唤醒中断不可调用flash内代码。
    // LowPower_Sleep(RB_PWR_RAM30K | RB_PWR_RAM2K); //只保留30+2K SRAM 供电
    // Kaygle modified 20240223 -- 替代LowPower_Sleep，老函数的有概率死机，主要是唤醒后flash有概率不稳定，要延时一小下
    uint8_t  x32Kpw, x32Mpw;
    uint16_t DCDCState;
    x32Kpw = R8_XT32K_TUNE;
    x32Mpw = R8_XT32M_TUNE;
    x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流
    if (R16_RTC_CNT_32K > 0x3fff)
    {                                    // 超过500ms
        x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE驱动电流降低到额定电流
    }

    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
    SAFEOPERATE;
    R8_BAT_DET_CTRL = 0; // 关闭电压监控
    R8_XT32K_TUNE = x32Kpw;
    R8_XT32M_TUNE = x32Mpw;
    R8_SAFE_ACCESS_SIG = 0;

    PFIC->SCTLR |= (1 << 2); //deep sleep

    DCDCState = R16_POWER_PLAN & (RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE);
    DCDCState |= RB_PWR_PLAN_EN | RB_PWR_MUST_0010 | RB_PWR_CORE | RB_PWR_RAM30K | RB_PWR_RAM2K;
    __nop();
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
    SAFEOPERATE;
    R8_SLP_POWER_CTRL |= RB_RAM_RET_LV;
    R8_PLL_CONFIG |= (1 << 5);
    R16_POWER_PLAN = DCDCState;
    __WFE();
    __nop();
    __nop();
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
    R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
    SAFEOPERATE;
    R8_PLL_CONFIG &= ~(1 << 5);
    R8_SAFE_ACCESS_SIG = 0;
    DelayUs(100);
#endif
    // LowPower_Halt()
    HSECFG_Current(HSE_RCur_100);                 // 降为额定电流(低功耗函数中提升了HSE偏置电流)
    return;
}
// battery detection interrupt config
void BatteryInit(void)
{
#if (ZQ_FUNC_BATTERY == 1)
    // 配置GPIO - PB1 下降沿中断,  每秒计数满3次表示电池不存在
    GPIO_ModeCfg(zy_ios.batt_chrg, GPIO_ModeIN_PU);
    GPIO_ITModeCfg(zy_ios.batt_chrg, GPIO_ITMode_FallEdge); // 下降沿触发
#endif
}
// humman counter init
void HummanCounterInit(void)
{
    if (ZyIsGPIOValid(zy_ios.det_human)) {
        // 配置GPIO - PA10 下降沿中断
        GPIO_ModeCfg(zy_ios.det_human, GPIO_ModeIN_PU);
        GPIO_ITModeCfg(zy_ios.det_human, GPIO_ITMode_HighLevel); // 高电平触发
    }
}
int PowRead12vState(void)
{
    GPIO_ModeCfg(zy_ios.det_12v, GPIO_ModeIN_Floating);	//重要涉及休眠唤醒IO, 检测前重新配置，防止外部干扰导致I/O模式错误
    return GPIO_ReadPortPin(zy_ios.det_12v) ? 1 : 0;
}
// return NUM_INVALID_WORD if no battery or last_state value
short BatteryUpdateState(int span_s, short last_state)
{
    short state = NUM_INVALID_WORD;
    // 原理：充电芯片TC4056A, 目前电路下, 无电池时，chrg脚输出大约4-7Hz脉冲, 
    // zy_ios.batt_chrg脚会被脉冲中断, 记录脉冲次数
    // 充电芯片TC4056A, chrg脚输出大约4-7Hz脉冲, 表明无电池, 保险一下, 阈值计数3个/s
#if (ZQ_FUNC_BATTERY == 1)
    if (span_s > 0) {
        if(hal_battery_plus < (uint32_t)(3 * span_s)) state = 1;
        else state = NUM_INVALID_WORD;
        hal_battery_plus = 0;   // 该变量中断也使用, 没加保护, 分析应该没问题。
        return state;
    }
#endif
	return last_state;
}

void BuzzorSwitch(int isOn)
{
#ifndef ZQ_SIMULATOR
    if (isOn) {
        GPIO_ModeCfg(zy_ios.buzzor, GPIO_ModeOut_PP_5mA);
        // GPIOPinRemap(ENABLE, RB_PIN_PWMX);
        PWMX_CLKCfg(60);        // 基准频率：Fbase = Fsys/60 = 32M/60
        PWMX_CycleCfg(PWMX_Cycle_256); // 周期：256 * Fbase
        PWMX_ACTOUT(CH_PWM5, 256 / 2, Low_Level, ENABLE); // PWM通道8，50%占空比
    }
    else {
        PWMX_ACTOUT(CH_PWM5, 256 / 2, Low_Level, DISABLE);
        GPIO_ResetBits(zy_ios.buzzor);  //Beep Off
    }
#else   // ZQ_SIMULATOR
    SimuBuzzor(isOn);
#endif  //ZQ_SIMULATOR
}

void BuzzorAlarm(int isOn)
{
    if (!isOn) { // 关报警音
        BuzzorSwitch(0);
        return;
    }
    // 报警声音频率为2次 / 秒，响1秒停1秒
    int x = (int)(zq_timer_50ms % 1600);
    if(x > 600)
        BuzzorSwitch(0);
    else if (x > 400)
        BuzzorSwitch(1);
    else if (x > 200)
        BuzzorSwitch(0);
    else
        BuzzorSwitch(1);
    return;
}


//  测试辅助代码 -----------------------------------------------------------------------------------------------
int zy_test_cnt = 0;
extern void BuzzorSwitch(int isOn);
// 蜂鸣器响100ms
void TestBuzzor100ms(void)
{
    WdtClean();
    BuzzorSwitch(1);
    DelayMs(100); 
    BuzzorSwitch(0);
    WdtClean();
}
// 测试函数,发出咔哒
void TestSpeechKata1(void)
{
    GPIO_ModeCfg(zy_ios.motor, GPIO_ModeOut_PP_20mA);	//MOTOR_EN
    WdtClean();
    GPIO_InverseBits(zy_ios.motor);
    DelayMs(50);
    GPIO_InverseBits(zy_ios.motor);
    DelayMs(50);
    WdtClean();
}
